package server;

import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.io.*;
import java.net.*;

import model.Master;


public class Server {

	int poolsize = 0;
	int port = 3141;

	/*
	 * - Server use Port 3141, - Server-Socket shut down with "Strg+C" 

	 */

	/**
	 * launch Server with Cached Clientpool
	 * @throws IOException
	 */
	public Server() throws IOException {
		startServer();
	}

	/**
	 * launch Server with restricted Clientpool
	 * @param poolsize
	 * @throws IOException
	 */
	public Server(int poolsize) throws IOException {
		this.poolsize = poolsize;
		startServer();
	}
	/**
	 * generated probertie File 
	 * 	Content: Server IP
	 */
	public void setProbertieFile() {
		
    	Properties prop = new Properties();
    	String[] temp = null;
    	String str=null;
    	try {
    		str=InetAddress.getLocalHost().toString();
    		//System.out.println("Properties Server IP: "+InetAddress.getLocalHost());
    		System.out.println("Properties Server IP: "+str);
			temp = str.split("/");
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	try {
    		//set the properties value
    		//prop.setProperty("serverip", temp[1]);
    		prop.setProperty("serverip", str);
    		prop.setProperty("socket", Integer.toString(port));
    		//save properties to project root folder
    		prop.store(new FileOutputStream("config.properties"), null);
 
    	} catch (IOException ex) {
    		ex.printStackTrace();
        }
	}

	/**
	 * Launch Server
	 * 
	 * @throws IOException
	 */
	public void startServer() throws IOException {
		final ExecutorService pool;
		final ServerSocket serverSocket;
		String zusatz;
		System.out.println("Server runs.....");
		setProbertieFile();
		if (poolsize==0) {
			//create a new Threadpool, 
			// genrate new threads on demand
			// Primarily, free threads are used.
			pool = Executors.newCachedThreadPool();
			zusatz = "CachedThreadPool";
		} else {
			// create a new Threadpool with poolSize 
			pool = Executors.newFixedThreadPool(poolsize);
			zusatz = "poolsize=" + poolsize;
		}
		serverSocket = new ServerSocket(port);
		
		
		
		// Thread manage the Client-Server-Communication
		Thread t1 = new Thread(new NetworkService(pool, serverSocket));
		System.out.println("Start NetworkService(Multiplikation), " + zusatz
				+ ", Thread: " + Thread.currentThread());
		t1.start();
		//  act on  Strg+C -> shutdown
		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				System.out.println("Strg+C, pool.shutdown");
				pool.shutdown(); 

				try {
					// wait 4 seconds before shut down
					pool.awaitTermination(4L, TimeUnit.SECONDS);
					if (!serverSocket.isClosed()) {
						System.out.println("ServerSocket close");
						serverSocket.close();
					}
				} catch (IOException e) {
				} catch (InterruptedException ei) {
				}
			}
			
		});
		//
		try {
			t1.join();
		} catch (InterruptedException e) {
			System.out.println("NetworkService waoting error");
			e.printStackTrace();
		}
	}
}